package com.irdstudio.efp.esb.service.impl.zx;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.irdstudio.basic.framework.core.constant.CertTypeConstant;
import com.irdstudio.basic.framework.core.util.Try;
import com.irdstudio.cdp.pboc.service.facade.Pboc5yearsOverdueService;
import com.irdstudio.cdp.pboc.service.facade.PbocAssetDetailService;
import com.irdstudio.cdp.pboc.service.facade.PbocBadDebtsService;
import com.irdstudio.cdp.pboc.service.facade.PbocBondsmanService;
import com.irdstudio.cdp.pboc.service.facade.PbocCarService;
import com.irdstudio.cdp.pboc.service.facade.PbocCivilJudgementService;
import com.irdstudio.cdp.pboc.service.facade.PbocCreditBasicService;
import com.irdstudio.cdp.pboc.service.facade.PbocCreditGuaranteelDetailService;
import com.irdstudio.cdp.pboc.service.facade.PbocCreditPromptService;
import com.irdstudio.cdp.pboc.service.facade.PbocCreditStatusService;
import com.irdstudio.cdp.pboc.service.facade.PbocCreditThousandService;
import com.irdstudio.cdp.pboc.service.facade.PbocCreditqueryDetailService;
import com.irdstudio.cdp.pboc.service.facade.PbocCreditquerySummaryService;
import com.irdstudio.cdp.pboc.service.facade.PbocDeliverySumService;
import com.irdstudio.cdp.pboc.service.facade.PbocDescriptionService;
import com.irdstudio.cdp.pboc.service.facade.PbocEndowmentInsurancecacheService;
import com.irdstudio.cdp.pboc.service.facade.PbocEndowmentInsurancegrantService;
import com.irdstudio.cdp.pboc.service.facade.PbocForcecarryService;
import com.irdstudio.cdp.pboc.service.facade.PbocHouseprovidentService;
import com.irdstudio.cdp.pboc.service.facade.PbocIdentityService;
import com.irdstudio.cdp.pboc.service.facade.PbocJobService;
import com.irdstudio.cdp.pboc.service.facade.PbocLoadBasicService;
import com.irdstudio.cdp.pboc.service.facade.PbocLoadGuaranteelDetailService;
import com.irdstudio.cdp.pboc.service.facade.PbocLoadOverdueService;
import com.irdstudio.cdp.pboc.service.facade.PbocLoadStatusService;
import com.irdstudio.cdp.pboc.service.facade.PbocLowIncomeService;
import com.irdstudio.cdp.pboc.service.facade.PbocNearcreditStatusService;
import com.irdstudio.cdp.pboc.service.facade.PbocNoneSettleService;
import com.irdstudio.cdp.pboc.service.facade.PbocNoneworkoffCreditcardService;
import com.irdstudio.cdp.pboc.service.facade.PbocNoneworkoffNearcreditcardService;
import com.irdstudio.cdp.pboc.service.facade.PbocOtherInfoService;
import com.irdstudio.cdp.pboc.service.facade.PbocOwingTaxesService;
import com.irdstudio.cdp.pboc.service.facade.PbocPracticReqService;
import com.irdstudio.cdp.pboc.service.facade.PbocPunishService;
import com.irdstudio.cdp.pboc.service.facade.PbocResidenceService;
import com.irdstudio.cdp.pboc.service.facade.PbocRewardService;
import com.irdstudio.cdp.pboc.service.facade.PbocSpecialTradeService;
import com.irdstudio.cdp.pboc.service.facade.PbocSponsorialDetailService;
import com.irdstudio.cdp.pboc.service.facade.PbocSpouseService;
import com.irdstudio.cdp.pboc.service.facade.PbocTelecomService;
import com.irdstudio.cdp.pboc.service.facade.QueryReportService;
import com.irdstudio.cdp.pboc.service.vo.Pboc5yearsOverdueVO;
import com.irdstudio.cdp.pboc.service.vo.PbocOtherInfoVO;
import com.irdstudio.cdp.pboc.service.vo.PbocSpecialTradeVO;
import com.irdstudio.cdp.pboc.service.vo.QueryReportVO;
import com.irdstudio.efp.esb.common.constant.ESBTradeNoConstance;
import com.irdstudio.efp.esb.common.constant.ZXReturnType;
import com.irdstudio.efp.esb.service.bo.req.BaseZXReqBean;
import com.irdstudio.efp.esb.service.bo.req.ZX10001QueryReports;
import com.irdstudio.efp.esb.service.bo.req.ZX10001QueryReports.Builder;
import com.irdstudio.efp.esb.service.bo.resp.zx.BaseZXResBean;
import com.irdstudio.efp.esb.service.bo.resp.zx.ZX10001JSONResponseReport;
import com.irdstudio.efp.esb.service.vo.zx.ZXVO;

/**
 * @description:征信单笔查询接口-JSON
 * @date:2018年12月20日 下午2:31:11
 * @author:hengyh
 */
@Service("zx10001JSONService")
@DependsOn("ZXConfig")// 确保ZXConfig配置类bean先被容器创建
public class ZX10001JSONServiceImpl extends BaseZXService<ZX10001QueryReports, ZX10001JSONResponseReport> {

	private static Logger log = LoggerFactory.getLogger(ZX10001JSONServiceImpl.class);
	public static final String INTERFACE_ID = "10001";
	private final String vertType = "30";

	@Override
	protected void preProcess(BaseZXReqBean<ZX10001QueryReports> reqBean) {
		ZX10001QueryReports queryReports = reqBean.getQryRptsInfArry().get(0);
		queryReports = new Builder()
				.buildWithExists(queryReports)
				.withIntfInd(INTERFACE_ID)
				.withRptFmt(vertType)
				.withRptAgng(config.getValidDay())
				.withRtnType(ZXReturnType.JSON.VALUE)
				.withCertTp(CertTypeConstant.CODE_10100)
				.build();
		log.debug("进入征信单笔查询接口，参数：" + Objects.toString(queryReports));
	}

	@Override
	protected String tradeNo() {
		return ESBTradeNoConstance.ZX10001;
	}

	@Override
	protected String scene() {
		return "01";
	}

	@Override
	protected Function<String, BaseZXResBean<ZX10001JSONResponseReport>> converter() {
		return i -> JSONObject.parseObject(i, new TypeReference<BaseZXResBean<ZX10001JSONResponseReport>>() {});
	}

	@Autowired
	private QueryReportService QueryReportService;
	@Autowired
	private PbocIdentityService PbocIdentityService;
	@Autowired
	private PbocSpouseService PbocSpouseService;
	@Autowired
	private PbocResidenceService PbocResidenceService;
	@Autowired
	private PbocJobService PbocJobService;
	@Autowired
	private PbocCreditPromptService PbocCreditPromptService;
	@Autowired
	private PbocCreditThousandService PbocCreditThousandService;
	@Autowired
	private PbocBadDebtsService PbocBadDebtsService;
	@Autowired
	private PbocDeliverySumService PbocDeliverySumService;
	@Autowired
	private PbocNoneSettleService PbocNoneSettleService;
	@Autowired
	private PbocNoneworkoffCreditcardService PbocNoneworkoffCreditcardService;
	@Autowired
	private PbocNoneworkoffNearcreditcardService PbocNoneworkoffNearcreditcardService;
	@Autowired
	private PbocBondsmanService PbocBondsmanService;
	@Autowired
	private PbocAssetDetailService PbocAssetDetailService;
	@Autowired
	private PbocSponsorialDetailService PbocSponsorialDetailService;
	@Autowired
	private PbocLoadBasicService PbocLoadBasicService;
	@Autowired
	private PbocLoadStatusService PbocLoadStatusService;
	@Autowired
	private PbocLoadOverdueService PbocLoadOverdueService;
	@Autowired
	private PbocCreditBasicService PbocCreditBasicService;
	@Autowired
	private PbocCreditStatusService PbocCreditStatusService;
	@Autowired
	private PbocNearcreditStatusService PbocNearcreditStatusService;
	@Autowired
	private PbocLoadGuaranteelDetailService PbocLoadGuaranteelDetailService;
	@Autowired
	private PbocCreditGuaranteelDetailService PbocCreditGuaranteelDetailService;
	@Autowired
	private PbocOwingTaxesService PbocOwingTaxesService;
	@Autowired
	private PbocCivilJudgementService PbocCivilJudgementService;
	@Autowired
	private PbocForcecarryService PbocForcecarryService;
	@Autowired
	private PbocPunishService PbocPunishService;
	@Autowired
	private PbocHouseprovidentService PbocHouseprovidentService;
	@Autowired
	private PbocEndowmentInsurancecacheService PbocEndowmentInsurancecacheService;
	@Autowired
	private PbocEndowmentInsurancegrantService PbocEndowmentInsurancegrantService;
	@Autowired
	private PbocLowIncomeService PbocLowIncomeService;
	@Autowired
	private PbocPracticReqService PbocPracticReqService;
	@Autowired
	private PbocRewardService PbocRewardService;
	@Autowired
	private PbocCarService PbocCarService;
	@Autowired
	private PbocTelecomService PbocTelecomService;
	@Autowired
	private PbocDescriptionService PbocDescriptionService;
	@Autowired
	private PbocCreditquerySummaryService PbocCreditquerySummaryService;
	@Autowired
	private PbocCreditqueryDetailService PbocCreditqueryDetailService;
	@Autowired
	private Pboc5yearsOverdueService Pboc5yearsOverdueService;
	@Autowired
	private PbocSpecialTradeService PbocSpecialTradeService;
	@Autowired
	private PbocOtherInfoService PbocOtherInfoService;
	@Override
	protected ZXVO postProcess(BaseZXReqBean<ZX10001QueryReports> reqBean,
							   BaseZXResBean<ZX10001JSONResponseReport> resBean) throws Exception {
		// 先查询是否存在已有的查询结果,如果已有那么直接返回不进行落库
		/*String certCode = reqBean.getQryRptsInfArry().get(0).getCertNo();
		if (certCode.length() == 18) {
			log.info("身份证号：" + certCode);
			return new ZXVO(Boolean.TRUE, certCode); // 挡板 SIT测试 TODO
		}*/

		ZX10001JSONResponseReport content = resBean.getRepRptsInfArry().get(0);
		String reportId = content.getRptNo();
		ZXVO zxvo = new ZXVO(Boolean.TRUE, reportId);
		QueryReportVO queryReportVo = new QueryReportVO();
		queryReportVo.setReportId(reportId);
		if (QueryReportService.queryByPk(queryReportVo) != null) {
			log.info("已存在查询结果，不进行落库，报告编号：" + reportId);
			return zxvo;
		}
		Optional.ofNullable(content.getQueryReport()).ifPresent(Try.ofConsumer(QueryReportService::insertQueryReport));
		Optional.ofNullable(content.getReportIdentity()).filter(i -> i.getPId() != null).ifPresent(Try.ofConsumer(PbocIdentityService::insertPbocIdentity));
		Optional.ofNullable(content.getReportSpouse()).filter(i -> i.getPId() != null).ifPresent(Try.ofConsumer(PbocSpouseService::insertPbocSpouse));
		Optional.ofNullable(content.getResdntInfArry()).ifPresent(i ->
				i.forEach(Try.ofConsumer(PbocResidenceService::insertPbocResidence)));
		Optional.ofNullable(content.getCrrInfArry()).ifPresent(i ->
				i.forEach(Try.ofConsumer(PbocJobService::insertPbocJob)));
		Optional.ofNullable(content.getReportCreditPrompt()).filter(i -> i.getPId() != null)
				.ifPresent(Try.ofConsumer(PbocCreditPromptService::insertPbocCreditPrompt));
		Optional.ofNullable(content.getReportCreditThousand()).filter(i -> i.getPId() != null)
				.ifPresent(Try.ofConsumer(PbocCreditThousandService::insertPbocCreditThousand));
		Optional.ofNullable(content.getReportBadDebts()).filter(i -> i.getPId() != null).ifPresent(Try.ofConsumer(PbocBadDebtsService::insertPbocBadDebts));
		Optional.ofNullable(content.getReportDeliverySum()).filter(i -> i.getPId() != null).ifPresent(Try.ofConsumer(PbocDeliverySumService::insertPbocDeliverySum));
		Optional.ofNullable(content.getReportNoneSettle()).filter(i -> i.getPId() != null).ifPresent(Try.ofConsumer(PbocNoneSettleService::insertPbocNoneSettle));
		Optional.ofNullable(content.getReportNoneworkoffCreditcard()).filter(i -> i.getPId() != null)
				.ifPresent(Try.ofConsumer(PbocNoneworkoffCreditcardService::insertPbocNoneworkoffCreditcard));
		Optional.ofNullable(content.getReportNoneworkoffNearcreditcard()).filter(i -> i.getPId() != null)
				.ifPresent(Try.ofConsumer(PbocNoneworkoffNearcreditcardService::insertPbocNoneworkoffNearcreditcard));
		Optional.ofNullable(content.getReportBondsman()).filter(i -> i.getPId() != null).ifPresent(Try.ofConsumer(PbocBondsmanService::insertPbocBondsman));
		Optional.ofNullable(content.getAstDispInfoArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocAssetDetailService::insertPbocAssetDetail));
		});
		Optional.ofNullable(content.getGuarCmpnstInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocSponsorialDetailService::insertPbocSponsorialDetail));
		});
		List<Pboc5yearsOverdueVO> FvYrOdueInfArry = new ArrayList<>();
		List<PbocSpecialTradeVO> SpclTxnInfArry = new ArrayList<>();
		List<PbocOtherInfoVO> OthrExpInfArry = new ArrayList<>();
		Optional.ofNullable(content.getLoanBscInfArry()).ifPresent(i -> {
			i.stream().filter(j -> j.getPId() != null).forEach(Try.ofConsumer(j -> {
				PbocLoadBasicService.insertPbocLoadBasic(j);
				Optional.ofNullable(j.getLoanStInfArry()).filter(k -> k.getPId() != null)
						.ifPresent(Try.ofConsumer(PbocLoadStatusService::insertPbocLoadStatus));
				Optional.ofNullable(j.getLoanCrnOdueInfArry()).filter(k -> k.getPId() != null)
						.ifPresent(Try.ofConsumer(PbocLoadOverdueService::insertPbocLoadOverdue));
				Optional.ofNullable(j.getFvYrOdueInfArry()).ifPresent(Try.ofConsumer(FvYrOdueInfArry::addAll));
				Optional.ofNullable(j.getSpclTxnInfArry()).ifPresent(Try.ofConsumer(SpclTxnInfArry::addAll));
				Optional.ofNullable(j.getOthrExpInfArry()).ifPresent(Try.ofConsumer(OthrExpInfArry::addAll));
			}));
		});
		Optional.ofNullable(content.getCrCardBscInfArry()).ifPresent(i -> {
			i.stream().filter(j -> j.getPId() != null).forEach(Try.ofConsumer(j -> {
				PbocCreditBasicService.insertPbocCreditBasic(j);
				Optional.ofNullable(j.getCrCardStInfArry()).filter(k -> k.getPId() != null)
						.ifPresent(Try.ofConsumer(PbocCreditStatusService::insertPbocCreditStatus));
				Optional.ofNullable(j.getPrepCrCardStInfArry()).filter(k -> k.getPId() != null)
						.ifPresent(Try.ofConsumer(PbocNearcreditStatusService::insertPbocNearcreditStatus));
				Optional.ofNullable(j.getFvYrOdueInfArry()).ifPresent(Try.ofConsumer(FvYrOdueInfArry::addAll));
				Optional.ofNullable(j.getSpclTxnInfArry()).ifPresent(Try.ofConsumer(SpclTxnInfArry::addAll));
				Optional.ofNullable(j.getOthrExpInfArry()).ifPresent(Try.ofConsumer(OthrExpInfArry::addAll));
			}));
		});
		FvYrOdueInfArry.forEach(Try.ofConsumer(Pboc5yearsOverdueService::insertPboc5yearsOverdue));
		SpclTxnInfArry.forEach(Try.ofConsumer(PbocSpecialTradeService::insertPbocSpecialTrade));
		OthrExpInfArry.forEach(Try.ofConsumer(PbocOtherInfoService::insertPbocOtherInfo));
		Optional.ofNullable(content.getExtGuarDtlInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocLoadGuaranteelDetailService::insertPbocLoadGuaranteelDetail));
		});
		Optional.ofNullable(content.getExtCrCardGuarInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocCreditGuaranteelDetailService::insertPbocCreditGuaranteelDetail));
		});
		Optional.ofNullable(content.getTaxArsRcrdInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocOwingTaxesService::insertPbocOwingTaxes));
		});
		Optional.ofNullable(content.getCrtNmRltVrdctRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocCivilJudgementService::insertPbocCivilJudgement));
		});
		Optional.ofNullable(content.getCrtNmEfrExecRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocForcecarryService::insertPbocForcecarry));
		});
		Optional.ofNullable(content.getAdminPnyRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocPunishService::insertPbocPunish));
		});
		Optional.ofNullable(content.getHsPblcPyRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocHouseprovidentService::insertPbocHouseprovident));
		});
		Optional.ofNullable(content.getPnsnInsPyRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocEndowmentInsurancecacheService::insertPbocEndowmentInsurancecache));
		});
		Optional.ofNullable(content.getPnsnInsDstrbtRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocEndowmentInsurancegrantService::insertPbocEndowmentInsurancegrant));
		});
		Optional.ofNullable(content.getLowIncmRcrdInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocLowIncomeService::insertPbocLowIncome));
		});
		Optional.ofNullable(content.getQulificationRcrdInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocPracticReqService::insertPbocPracticReq));
		});
		Optional.ofNullable(content.getAdminRwdRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocRewardService::insertPbocReward));
		});
		Optional.ofNullable(content.getVhcltTxnAdMrtgRcrdArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocCarService::insertPbocCar));
		});
		Optional.ofNullable(content.getSftPyRcrdInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocTelecomService::insertPbocTelecom));
		});
		Optional.ofNullable(content.getSelDclrInfArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocDescriptionService::insertPbocDescription));
		});
		Optional.ofNullable(content.getReportCreditquerySummary()).filter(i -> i.getPId() != null)
				.ifPresent(Try.ofConsumer(PbocCreditquerySummaryService::insertPbocCreditquerySummary));
		Optional.ofNullable(content.getLoanAprvQryRcrdDtlArry()).ifPresent(i -> {
			i.forEach(Try.ofConsumer(PbocCreditqueryDetailService::insertPbocCreditqueryDetail));
		});
		log.info("征信JSON格式查询结果落库完成，报告编号：" + reportId);
		return zxvo;
	}
}
